//// this signal uses the mouseX and mouseY position to build a signal
class MouseSaw implements AudioSignal
{
  void generate(float[] samp)
  {
    float range = map(mouseX, 0, width, 0, 1);
    float peaks = map(mouseY, 0, height, 1, 20);
    float inter = float(samp.length) / peaks;
    for ( int i = 0; i < samp.length; i += inter )
    {
      for ( int j = 0; j < inter && (i+j) < samp.length; j++ )
      {
        samp[i + j] = map(j, 0, inter, -range, range);
      }
    }
  }
 
  // this is a stricly mono signal
  void generate(float[] left, float[] right)
  {
    generate(left);
    generate(right);
  }
}



//
import ddf.minim.*;
import ddf.minim.signals.*;
import ddf.minim.effects.*;
import ddf.minim.analysis.*;
 
Minim minim;
AudioOutput out;
SquareWave square;
SineWave sine;
LowPassSP   lowpass;
FFT fft;

void setup()
{
  size(512, 200);
 
  minim = new Minim(this);
 
    // get a stereo line out with a sample buffer of 512 samples
  out = minim.getLineOut(Minim.STEREO, 512);
 
  // create a SquareWave with a frequency of 440 Hz, 
  // an amplitude of 1 and the same sample rate as out
  square = new SquareWave(440, 100, 44100);
  sine = new SineWave(1000, 1, 44100);
 
  // create a LowPassSP filter with a cutoff frequency of 200 Hz 
  // that expects audio with the same sample rate as out
  lowpass = new LowPassSP(200, 44100);
 
  // now we can attach the square wave and the filter to our output
  out.addSignal(sine);
  out.addEffect(lowpass);
  
  fft = new FFT(out.bufferSize(), out.sampleRate());
}

void draw()
{
  background(0);
//  stroke(255);
//  // we draw the waveform by connecting neighbor values with a line
//  // we multiply each of the values by 50 
//  // because the values in the buffers are normalized
//  // this means that they have values between -1 and 1. 
//  // If we don't scale them up our waveform 
//  // will look more or less like a straight line.
//  for(int i = 0; i < out.bufferSize() - 1; i++)
//  {
//    line(i, 50 + out.left.get(i)*50, i+1, 50 + out.left.get(i+1)*50);
//    line(i, 150 + out.right.get(i)*50, i+1, 150 + out.right.get(i+1)*50);
//  }
  
  stroke(255, 0, 0, 128);
  // draw the spectrum as a series of vertical lines
  // I multiple the value of getBand by 4 
  // so that we can see the lines better

  for(int i = 0; i < fft.specSize(); i++)
  {
    line(i, height, i, height - fft.getBand(i)*4);
    if(fft.getBand(i) > 0)
      println(fft.getBand(i));
  }
 
  stroke(255);
  // I draw the waveform by connecting 
  // neighbor values with a line. I multiply 
  // each of the values by 50 
  // because the values in the buffers are normalized
  // this means that they have values between -1 and 1. 
  // If we don't scale them up our waveform 
  // will look more or less like a straight line.
  for(int i = 0; i < out.left.size() - 1; i++)
  {
    line(i, 50 + out.left.get(i)*50, i+1, 50 + out.left.get(i+1)*50);
    line(i, 150 + out.right.get(i)*50, i+1, 150 + out.right.get(i+1)*50);
  }
  
  
}

// here we provide a way to mute out
// because, let's face it, it's not a very pleasant sound
void keyPressed()
{
  if ( key == 'm' )
  {
    if ( out.isMuted() )
    {
      out.unmute();
    }
    else
    {
      out.mute();
    }
  }
}
 
void stop()
{
  out.close();
  minim.stop();
 
  super.stop();
}
